package pl.cezary.butler.walili.common;

import java.util.*;

public enum TaskStatus {

    /**
     * <p style="margin-top: 0"> Status dla zadan ktore zostaly pobrane przez
     * klienta ale nie zostal zwrocony przez niego wynik w ustalonym czasie <br>
     * </p> <p style="margin-top: 0"> . </p>
     */
    PRZERWANE {

        @Override
        public boolean czyPrzejscieDozwolone(TaskStatus zad) {
            return zad == PRZETWARZANE || zad == this;
        }

        @Override
        public TaskStatus zmienStatusSerwer(TaskStatus zad) {
            return this;
        }
    },
    /**
     * <p style="margin-top: 0"> Status dla zadania przeznaczonego do ponownej
     * weryfikacji. Zadania sa wznawiane jezeli sa spelnione warunki.<br>1.
     * Zadanie jest w stanie sukces lub porazka <br>2. Uplynol duzy czas od
     * ostatniej weryfikacji zadania (kilka dni/tygodni) </p>
     */
    WZNOWIONE {

        @Override
        public boolean czyPrzejscieDozwolone(TaskStatus zad) {
            final boolean temp = super.czyPrzejscieDozwolone(zad);
            return temp || zad == PRZETWARZANE;
        }
    },
    /**
     * <p style="margin-top: 0"> Status dla zadan ktorych wykonanie powiodlo
     * sie. </p>
     */
    SUKCES(WZNOWIONE) {

        @Override
        public TaskStatus zmienStatusSerwer(TaskStatus zad) {
            switch (zad) {
                case PORAZKA:
                    return PORAZKA;
                default:
                    return this;
            }
        }
    },
    /**
     * <p style="margin-top: 0"> Status dla zadan ktorych wykonanie nie powiodlo
     * sie. Tzn nie udalo sie uzyskac dostepu do zasobu. </p>
     */
    PORAZKA(WZNOWIONE),
    /**
     * <p style="margin-top: 0"> Status dla zadan ktore zostaly pobrane przez
     * klienta. </p>
     */
    PRZETWARZANE(PORAZKA, SUKCES, PRZERWANE),
    /**
     * <p style="margin-top: 0"> Stan pocz&#261;tkowy, zadania s&#261; w tym
     * stanie tylko natychmiast po dodaniu przez uzytkownika. </p>
     */
    NOWE(PRZETWARZANE);
    private final Set<TaskStatus> dozwolonePrzejscia;

    private TaskStatus(TaskStatus... st) {                  
        dozwolonePrzejscia = new TreeSet<TaskStatus>(Arrays.asList(st));
    }

    /**
     * Metoda sprawdzajaca czy mozliwe jest przejscie miedzy stanem obecnym a
     * stanem
     * <code>stat</code>.
     *
     * @param stat proponowany nowy status
     * @return
     * <code>true</code> jezeli przejscie jest dowolone,
     * <code>false</code> w przeciwnym przypadku
     */
    public boolean czyPrzejscieDozwolone(TaskStatus stat) {
        return stat == this || dozwolonePrzejscia.contains(stat);
    }

    /**
     * Metoda rozwiazujaca problem z przejsciami miedzy stanami na serwerze
     * kiedy dwukrotnie zostanie wykonane to samo zadanie
     *
     * @param stat status
     * @return status wybrany status ktory powinien zostac ustawiony
     */
    public TaskStatus zmienStatusSerwer(TaskStatus stat) {
        throw new UnsupportedOperationException("Nie zaimplementowane");
    }
}
